#include "QC.h"
#include "string.h"

#define QC_DP_RET_MIN_VOLT 500
#define QC_DP_RET_MAX_VOLT 700
#define QC_DETECT_LOOP_TIMES (QC_DETECT_PERIOD_MS / QC_LOOP_CALL_DURATION_MS)
#define QC_DETECT_TIME_POINT (QC_DETECT_TIMEPOINT / QC_LOOP_CALL_DURATION_MS)
typedef struct
{
    unsigned int index;
    QCInitParms initParms;
    QCVoltEnum volt;
    unsigned int time;
    QCSupportRetEnum ret;
} QCHandlerContext;
static unsigned int QCContextIndex = 0;
static QCHandlerContext contextTalbe[QC_MAX_CONTEXT]; //

QCHandler *QCInit(QCInitParms *parms, QCVoltEnum volt)
{
    QCHandlerContext *ctx;
    ctx = &contextTalbe[QCContextIndex];
    ctx->index = QCContextIndex;
    memcpy(&ctx->initParms, parms, sizeof(QCInitParms));
    QCContextIndex++;
    ctx->volt = volt;
    ctx->time = 0;
    ctx->initParms.setDP(QC_SET_FLOAT);
    ctx->initParms.setDN(QC_SET_FLOAT);
    ctx->ret = QC_BUSY;

    return (QCHandler *)ctx;
}

QCSupportRetEnum isSupportQCProtocol(QCHandler *handler)
{
    QCHandlerContext *ctx = (QCHandlerContext *)handler;

    if (ctx->ret != QC_BUSY)
    {
        return ctx->ret;
    }

    if (ctx->time < QC_DETECT_LOOP_TIMES)
    {
        if (ctx->initParms.getDNVoltmv() < QC_DP_RET_MIN_VOLT)
        {
            ctx->ret = QC_SUPPORT;
        }
        else if (ctx->initParms.getDNVoltmv() > QC_DP_RET_MAX_VOLT)
        {
            ctx->ret = QC_NOT_SUPPORT;
        }
    }
    else
    {
        ctx->ret = QC_NOT_SUPPORT;
    }
    return ctx->ret;
}

void setQCVolt(QCHandler *handler, QCVoltEnum volt)
{
    QCHandlerContext *ctx = (QCHandlerContext *)handler;
    switch (volt)
    {
    case QC_5V:
        ctx->initParms.setDP(QC_SET_600mv);
        ctx->initParms.setDN(QC_SET_0V);
        break;
    case QC_9V:
        ctx->initParms.setDP(QC_SET_3300mv);
        ctx->initParms.setDN(QC_SET_600mv);
        break;
    case QC_12V:
        ctx->initParms.setDP(QC_SET_600mv);
        ctx->initParms.setDN(QC_SET_600mv);
        break;
    case QC_20V:
        ctx->initParms.setDP(QC_SET_3300mv);
        ctx->initParms.setDN(QC_SET_3300mv);
        break;
    default:
        break;
    }
}
// 检测QC
// 请以QC_LOOP_CALL_DURATION_MS的时间间隔进行调用
void QCLoop(QCHandler *handler)
{
    unsigned int dnVolt = 0;
    QCHandlerContext *ctx = (QCHandlerContext *)handler;

    if (ctx->time >= QC_DETECT_LOOP_TIMES)
    {
        if (isSupportQCProtocol(handler) == QC_SUPPORT)
        {
            setQCVolt(handler, ctx->volt);
        }
    }
    else
    {
        if (ctx->time == 0)
        {
            ctx->initParms.setDP(QC_SET_600mv);
            ctx->initParms.setDN(QC_SET_FLOAT);
        }
        else if (ctx->time == QC_DETECT_TIME_POINT)
        {
            dnVolt = ctx->initParms.getDNVoltmv();
            if (dnVolt < QC_DP_RET_MIN_VOLT || dnVolt > QC_DP_RET_MAX_VOLT)
            {
                ctx->ret = QC_NOT_SUPPORT;
            }
        }
        
        ctx->time++;
    }

    ctx->initParms.getDPVoltmv();
    ctx->initParms.getDNVoltmv();
}
